package com.xuan.qimen.core.fei.shijia;

import com.nlf.calendar.EightChar;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import com.xuan.qimen.utils.CommonUtil;
import lombok.Getter;

import java.util.*;

/**
 * 飞盘奇门（时家、拆补法）
 *
 * @author KTY
 */
//@Data
@Getter
public class FeiShiJiaQiMen {

    /**
     * 公历日期
     */
    private Solar solar;
    /**
     * 农历日期
     */
    private Lunar lunar;
    /**
     * 星期
     */
    private String week;

    /**
     * 年干
     */
    private String yearGan;
    /**
     * 年支
     */
    private String yearZhi;
    /**
     * 年干支
     */
    private String yearGanZhi;

    /**
     * 月干
     */
    private String monthGan;
    /**
     * 月支
     */
    private String monthZhi;
    /**
     * 月干支
     */
    private String monthGanZhi;

    /**
     * 日干
     */
    private String dayGan;
    /**
     * 日支
     */
    private String dayZhi;
    /**
     * 日干支
     */
    private String dayGanZhi;

    /**
     * 时干
     */
    private String hourGan;
    /**
     * 时支
     */
    private String hourZhi;
    /**
     * 时干支
     */
    private String hourGanZhi;

    /**
     * 八字
     */
    private List<String> baZi;
    /**
     * 八字五行
     */
    private List<String> baZiWuXing;
    /**
     * 八字旬空
     */
    private List<String> baZiXunKong;
    /**
     * 八字纳音
     */
    private List<String> baZiNaYin;

    /**
     * 符头
     */
    private String fuTou;
    /**
     * 节气
     */
    private String jieQi;
    /**
     * 三元
     */
    private String sanYuan;
    /**
     * 阴阳遁
     */
    private String yinYangDun;
    /**
     * 局数
     */
    private int juShu;
    /**
     * 旬首
     */
    private String xunShou;
    /**
     * 旬首仪仗
     */
    private String xunShouYiZhang;
    /**
     * 旬首落宫
     */
    private int xunShouGong;
    /**
     * 值符
     */
    private String zhiFu;
    /**
     * 值使
     */
    private String zhiShi;
    /**
     * 旬空
     */
    private List<String> xunKong;
    /**
     * 六甲旬空
     */
    private List<String> liuJiaXunKong;
    /**
     * 六甲旬空落宫
     */
    private List<Integer> liuJiaXunKongGong;
    /**
     * 六甲旬空落宫标识（1~9宫）
     */
    private List<String> liuJiaXunKongGongMark;
    /**
     * 驿马
     */
    private String yiMa;
    /**
     * 驿马落宫
     */
    private int yiMaGong;
    /**
     * 驿马落宫标识（1~9宫）
     */
    private List<String> yiMaGongMark;
    /**
     * 天乙
     */
    private String tianYi;
    /**
     * 地乙
     */
    private String diYi;
    /**
     * 太乙
     */
    private String taiYi;
    /**
     * 六仪击刑
     */
    private List<String> liuYiJiXing;
    /**
     * 奇仪入墓
     */
    private List<String> qiYiRuMu;

    /**
     * 值符旋转前宫位
     */
    private int oldZhiFuGong;
    /**
     * 值符旋转后宫位
     */
    private int newZhiFuGong;

    /**
     * 值使旋转前宫位
     */
    private int oldZhiShiGong;
    /**
     * 值使旋转后宫位
     */
    private int newZhiShiGong;

    /**
     * 地盘（1~9宫）
     */
    private List<String> diPan;
    /**
     * 天盘（1~9宫）
     */
    private List<String> tianPan;
    /**
     * 人盘（1~9宫）
     */
    private List<String> renPan;
    /**
     * 神盘（1~9宫）
     */
    private List<String> shenPan;

    /**
     * 地盘，附带六甲隐位（1~9宫）
     */
    private List<String> diPanPron;
    /**
     * 地盘中的三奇六仪（1~9宫）
     */
    private List<String> diSanQiLiuYi;
    /**
     * 地盘中的六甲隐位（1~9宫）
     */
    private List<String> diLiuJiaYinWei;
    /**
     * 天盘飞盘后九星所携带的三奇六仪（1~9宫）
     */
    private List<String> tianPanQiYi;

    /**
     * 十干克应（1~9宫）
     */
    private List<String> shiGanKeYing;

    /**
     * 九遁（1~9宫）
     */
    private Map<Integer, List<String>> jiuDun;

    /**
     * 月将（如：子）
     */
    private String yueJiang;
    /**
     * 月将神（如：登明）
     */
    private String yueJiangShen;

//************************************************************************************************************************************

    /**
     * 使用默认设置初始化（默认使用当前公历日期）
     */
    public FeiShiJiaQiMen() {
        setData(new FeiShiJiaQiMenSetting()); // 获取并设置数据
    }

    /**
     * 使用公历日期初始化
     *
     * @param date 公历日期
     */
    public FeiShiJiaQiMen(Date date) {
        FeiShiJiaQiMenSetting setting = new FeiShiJiaQiMenSetting(date);
        setData(setting); // 获取并设置数据
    }

    /**
     * 使用日期初始化
     *
     * @param date     公历日期
     * @param dateType 日期类型（0:公历。1:农历）
     */
    public FeiShiJiaQiMen(Date date, int dateType) {
        FeiShiJiaQiMenSetting setting = new FeiShiJiaQiMenSetting(date, dateType);
        setData(setting); // 获取并设置数据
    }

    /**
     * 使用公历年月日时初始化
     *
     * @param year  公历年（0~9999）
     * @param month 公历月（1~12）
     * @param day   公历日
     * @param hour  公历时（0~24）
     */
    public FeiShiJiaQiMen(int year, int month, int day, int hour) {
        FeiShiJiaQiMenSetting setting = new FeiShiJiaQiMenSetting(year, month, day, hour);
        setData(setting); // 获取并设置数据
    }

    /**
     * 使用年月日时初始化
     *
     * @param year     年（0~9999）
     * @param month    月（1~12）
     * @param day      日
     * @param hour     时（0~24）
     * @param dateType 日期类型（0:公历。1:农历）
     */
    public FeiShiJiaQiMen(int year, int month, int day, int hour, int dateType) {
        FeiShiJiaQiMenSetting setting = new FeiShiJiaQiMenSetting(year, month, day, hour, dateType);
        setData(setting); // 获取并设置数据
    }

    /**
     * 使用自定义设置初始化（若未设置日期则默认使用当前公历日期）
     *
     * @param setting 设置
     */
    public FeiShiJiaQiMen(FeiShiJiaQiMenSetting setting) {
        setData(setting); // 获取并设置数据
    }

//====================================================================================================================================

    /**
     * 获取并设置数据
     *
     * @param setting 设置
     */
    private void setData(FeiShiJiaQiMenSetting setting) {

        // 初始化自定义数据
        initialize(setting);

        // 计算数据
        baZiData(); // 计算八字、八字五行、八字纳音、八字旬空
        fuTouAndJieQi(setting); // 计算符头和节气
        sanYuan(); // 计算三元
        yinYangDun(); // 计算阴阳遁
        juShu(); // 计算局数
        diQiYiLiuJia(); // 计算地盘中的[三奇六仪]和[六甲隐位]
        xunShou(); // 计算旬首
        xunKong(); // 计算旬空
        fuShi(); // 计算值符和值使
        liuJiaXunKong(); // 计算六甲旬空、落宫、标识
        yiMa(); // 计算驿马、落宫、标识
        diPan(); // 计算地盘
        tianPan(setting); // 计算天盘
        renPan(setting); // 计算人盘
        shenPan(setting); // 计算神盘
        tianYiDiYiTaiYi(); // 计算天乙、地乙、太乙
        liuYiJiXing(); // 计算六仪击刑
        qiYiRuMu(); // 计算奇仪入墓
        shiGanKeYing(); // 计算十干克应
        jiuDun(); // 计算九遁
        yueJiang(); // 计算月将、月将神

//        System.gc();

    }

    /**
     * 初始化自定义数据
     *
     * @param setting 设置
     */
    private void initialize(FeiShiJiaQiMenSetting setting) {

        // 1.1、☆判断日期类型并返回公历日期、农历日期
        Map<String, Object> DateTypeMap = FeiShiJiaQiMenUtil.isDateType(setting);
        // 1.2、设置日期
        this.solar = (Solar) DateTypeMap.get("solar"); // 设置公历日期
        this.lunar = (Lunar) DateTypeMap.get("lunar"); // 设置农历日期

        // 2、设置星期
        this.week = "周" + getLunar().getWeekInChinese();

        // 3.1、☆判断干支设置并返回干支
        Map<String, List<String>> ganZhiMap = FeiShiJiaQiMenUtil.isGanZhi(setting, getLunar());
        // 3.2、设置年干支
        List<String> yearGanZhi = ganZhiMap.get("yearGanZhi");
        this.yearGan = yearGanZhi.get(0); // 年干
        this.yearZhi = yearGanZhi.get(1); // 年支
        this.yearGanZhi = yearGanZhi.get(2); // 年干支
        // 3.3、设置月干支
        List<String> monthGanZhi = ganZhiMap.get("monthGanZhi");
        this.monthGan = monthGanZhi.get(0); // 月干
        this.monthZhi = monthGanZhi.get(1); // 月支
        this.monthGanZhi = monthGanZhi.get(2); // 月干支
        // 3.4、设置日干支
        List<String> dayGanZhi = ganZhiMap.get("dayGanZhi");
        this.dayGan = dayGanZhi.get(0); // 日干
        this.dayZhi = dayGanZhi.get(1); // 日支
        this.dayGanZhi = dayGanZhi.get(2); // 日干支
        // 3.5、设置时干支
        List<String> hourGanZhi = ganZhiMap.get("hourGanZhi");
        this.hourGan = hourGanZhi.get(0); // 时干
        this.hourZhi = hourGanZhi.get(1); // 时支
        this.hourGanZhi = hourGanZhi.get(2); // 时干支

    }

    /**
     * 获取八字、八字五行、八字纳音、八字旬空
     */
    private void baZiData() {

        EightChar ec = getLunar().getEightChar();

        // 1、设置八字
        this.baZi = Arrays.asList(getYearGanZhi(), getMonthGanZhi(), getDayGanZhi(), getHourGanZhi());

        // 2、设置八字五行
        this.baZiWuXing = Arrays.asList(ec.getYearWuXing(), ec.getMonthWuXing(), ec.getDayWuXing(), ec.getTimeWuXing());

        // 3、设置八字纳音
        this.baZiNaYin = Arrays.asList(ec.getYearNaYin(), ec.getMonthNaYin(), ec.getDayNaYin(), ec.getTimeNaYin());

        // 4、设置八字旬空
        this.baZiXunKong = Arrays.asList(ec.getYearXunKong(), ec.getMonthXunKong(), ec.getDayXunKong(), ec.getTimeXunKong());

    }

    /**
     * 计算符头和节气（TODO：待优化）
     */
    private void fuTouAndJieQi(FeiShiJiaQiMenSetting setting) {

        /*
            ★1、情况一：当天日干支是符头、当天是节气，则保存符头和节气

            ★2、情况二：当天日干支是符头、但当天不是节气，需保存符头并向前查找节气

            ★3、情况三：当天日干支不是符头、当天是节气，需保存节气并向前查找符头

            ★4、情况四：当天日干支不是符头、当天不是节气，需要按天向前查找符头和节气
                   1) 情况四之一：既碰到符头又碰到节气，则保存符头和节气
                   2) 情况四之二：若先碰到节气但未碰到符头，需保存节气并向前查找符头
                   3) 情况四之三：若先碰到符头但未碰到节气，需保存符头并向前查找节气
         */

        String dayGanZhi = getDayGanZhi(); // 日干支
        String[] sanYuanFuTou = FeiShiJiaQiMenMap.SAN_YUAN_FU_TOU; // 三元符头

        // ★1、情况一：当天日干支是符头、当天是节气，则保存符头和节气（▲例：农历二〇二二年八月廿八）
        for (String foTou : sanYuanFuTou) {
            if (dayGanZhi.equals(foTou) && !"".equals(getLunar().getJieQi())) {
                this.fuTou = dayGanZhi; // 保存符头
                this.jieQi = getLunar().getJieQi(); // 保存节气
                return;
            }
        }

        // ★2、情况二：当天日干支是符头、但当天不是节气，需保存符头并向前查找节气（▲例：农历二〇二二年八月十八）
        for (String foTou : sanYuanFuTou) {
            if (dayGanZhi.equals(foTou) && "".equals(getLunar().getJieQi())) {
                this.fuTou = dayGanZhi; // 保存符头
                this.jieQi = getLunar().getPrevJieQi(true).getName(); // 获取上一个节气（按天计算）
                return;
            }
        }

        // ★3、情况三：当天日干支不是符头、当天是节气，需保存节气并向前查找符头（▲例：农历二〇二二年八月十二）
        for (int i = 0; i < sanYuanFuTou.length; i++) {
            if (!dayGanZhi.equals(sanYuanFuTou[i]) && !"".equals(getLunar().getJieQi())) {
                String jieQi = getLunar().getJieQi(); // 当天节气
                // 3.1、获取向前第i天的日干支（晚子时日干支算明天）
                if (setting.getDayGanZhiSet() == FeiShiJiaQiMenEnum.DAY_GAN_ZHI_TOMORROW.getMark()) dayGanZhi = getLunar().next(-i).getDayInGanZhiExact();
                // 3.2、获取向前第i天的日干支（晚子时日柱算当天）
                if (setting.getDayGanZhiSet() == FeiShiJiaQiMenEnum.DAY_GAN_ZHI_TODAY.getMark()) dayGanZhi = getLunar().next(-i).getDayInGanZhiExact2();
                // 3.3、若向前第i天的日柱为符头则记录符头
                for (String foTou : sanYuanFuTou) {
                    if (dayGanZhi.equals(foTou)) {
                        this.fuTou = dayGanZhi; // 保存符头
                        this.jieQi = jieQi; // 保存节气
                        return;
                    }
                }
            }
        }

        // ★4、情况四：当天日干支不是符头、当天不是节气，需要按天向前查找符头和节气
        for (int i = 0; i < sanYuanFuTou.length; i++) {
            if (!dayGanZhi.equals(sanYuanFuTou[i]) && "".equals(getLunar().getJieQi())) {
                // 获取向前第i天的日干支（晚子时日干支算明天）
                if (setting.getDayGanZhiSet() == FeiShiJiaQiMenEnum.DAY_GAN_ZHI_TOMORROW.getMark()) dayGanZhi = getLunar().next(-i).getDayInGanZhiExact();
                // 获取向前第i天的日干支（晚子时日柱算当天）
                if (setting.getDayGanZhiSet() == FeiShiJiaQiMenEnum.DAY_GAN_ZHI_TODAY.getMark()) dayGanZhi = getLunar().next(-i).getDayInGanZhiExact2();
                String jieQi = getLunar().next(-i).getJieQi(); // 获取向前第i天的节气
                // 4.1、情况四之一：既碰到符头又碰到节气，则保存符头和节气（▲例：农历二〇二二年八月廿九）
                for (String foTou : sanYuanFuTou) {
                    if (dayGanZhi.equals(foTou) && !"".equals(jieQi)) {
                        this.fuTou = dayGanZhi; // 保存符头
                        this.jieQi = jieQi; // 保存节气
                        return;
                    }
                }
                // 4.2、情况四之二：若先碰到节气但未碰到符头，需保存节气并向前查找符头（▲例：农历二〇二〇年八月廿八）
                for (int j = 0; j < sanYuanFuTou.length; j++) {
                    if (!"".equals(jieQi) && !dayGanZhi.equals(sanYuanFuTou[i])) {
                        // 获取向前第i天的日干支（晚子时日干支算明天）
                        if (setting.getDayGanZhiSet() == FeiShiJiaQiMenEnum.DAY_GAN_ZHI_TOMORROW.getMark()) dayGanZhi = getLunar().next(-i).getDayInGanZhiExact();
                        // 获取向前第i天的日干支（晚子时日柱算当天）
                        if (setting.getDayGanZhiSet() == FeiShiJiaQiMenEnum.DAY_GAN_ZHI_TODAY.getMark()) dayGanZhi = getLunar().next(-i).getDayInGanZhiExact2();
                        // 若向前第i天的日柱为符头则记录符头
                        for (String foTou : sanYuanFuTou) {
                            if (dayGanZhi.equals(foTou)) {
                                this.fuTou = dayGanZhi; // 保存符头
                                this.jieQi = jieQi; // 保存节气
                                return;
                            }
                        }
                    }
                }
                // 4.3、情况四之三：若先碰到符头但未碰到节气，需保存符头并向前查找节气（▲例：农历二〇二二年八月十四）
                for (String foTou : sanYuanFuTou) {
                    if (dayGanZhi.equals(foTou) && "".equals(jieQi)) {
                        this.fuTou = dayGanZhi; // 保存符头
                        this.jieQi = getLunar().getPrevJieQi(true).getName(); // 保存节气
                        return;
                    }
                }
            }
        }

    }

    /**
     * 计算三元
     */
    private void sanYuan() {

        Map<Integer, List<String>> sanYuanRiZhu = FeiShiJiaQiMenMap.SAN_YUAN_RI_ZHU; // 三元日柱

        // 遍历三元日柱
        A:
        for (int i = 0; i < sanYuanRiZhu.size(); i++) {
            // 获取每一元中的干支
            List<String> yuanZhu = sanYuanRiZhu.get(i);
            // 判断日干支属于哪一元
            for (String value : yuanZhu) {
                if (getDayGanZhi().equals(value)) {
                    if (i == 0) {
                        this.sanYuan = FeiShiJiaQiMenConstant.SHANG_YUAN; // 上元
                    } else if (i == 1) {
                        this.sanYuan = FeiShiJiaQiMenConstant.ZHONG_YUAN; // 中元
                    } else if (i == 2) {
                        this.sanYuan = FeiShiJiaQiMenConstant.XIA_YUAN; // 下元
                    }
                    break A;
                }
            }
        }

    }

    /**
     * 计算阴阳遁
     */
    private void yinYangDun() {

        Map<Integer, List<String>> yinYangDun = FeiShiJiaQiMenMap.YIN_YANG_DUN; // 二十四节气对应阴阳遁

        // 遍历二十四节气对应阴阳遁
        A:
        for (int i = 0; i < yinYangDun.size(); i++) {
            // 获取阴阳遁的节气
            List<String> dun = yinYangDun.get(i);
            // 判断节气属于阴遁还是阳遁
            for (String value : dun) {
                if (getJieQi().equals(value)) {
                    if (i == 0) {
                        this.yinYangDun = FeiShiJiaQiMenConstant.YANG_DUN; // 阳遁
                    } else {
                        this.yinYangDun = FeiShiJiaQiMenConstant.YIN_DUN; // 阴遁
                    }
                    break A;
                }
            }
        }

    }

    /**
     * 计算局数
     */
    private void juShu() {

        Map<String, List<Integer>> juShu = FeiShiJiaQiMenMap.JU_SHU; // 二十四节气对应局数

        // 遍历二十四节气对应局数
        A:
        for (int i = 0; i < juShu.size(); i++) {
            // 获取节气对应的三元局数
            List<Integer> shu = juShu.get(getJieQi());
            for (int j = 0; j < shu.size(); j++) {
                // 根据三元判断所用局数
                switch (getSanYuan()) {
                    case FeiShiJiaQiMenConstant.SHANG_YUAN: // 上元
                        this.juShu = shu.get(0);
                        break A;
                    case FeiShiJiaQiMenConstant.ZHONG_YUAN: // 中元
                        this.juShu = shu.get(1);
                        break A;
                    case FeiShiJiaQiMenConstant.XIA_YUAN: // 下元
                        this.juShu = shu.get(2);
                        break A;
                }
            }
        }


    }

    /**
     * 计算地盘中的[三奇六仪]和[六甲隐位]
     */
    private void diQiYiLiuJia() {

        // 1.1、阳遁
        if (FeiShiJiaQiMenConstant.YANG_DUN.equals(getYinYangDun())) {
            this.diSanQiLiuYi = FeiShiJiaQiMenMap.DI_YANG_QI_YI.get(getJuShu()); // 保存三奇六仪
            this.diLiuJiaYinWei = FeiShiJiaQiMenMap.DI_YANG_LIU_JIA.get(getJuShu()); // 保存六甲隐位
        } else {
            // 1.2、阴遁
            this.diSanQiLiuYi = FeiShiJiaQiMenMap.DI_YIN_QI_YI.get(getJuShu()); // 保存三奇六仪
            this.diLiuJiaYinWei = FeiShiJiaQiMenMap.DI_YIN_LIU_JIA.get(getJuShu()); // 保存六甲隐位
        }

    }

    /**
     * 计算旬首
     */
    private void xunShou() {

        // 1、六十甲子对应的旬首
        Map<String, List<String>> sixJiaZiXunShou = FeiShiJiaQiMenMap.SIX_JIA_ZI_XUN_SHOU;

        // 2、根据时干支获取旬首
        String xunShou = sixJiaZiXunShou.get(getHourGanZhi()).get(0); // 旬首（如：甲子）
        String xunShouYiZhang = sixJiaZiXunShou.get(getHourGanZhi()).get(1); // 旬首仪仗（如：戊）

        // 3、设置旬首、旬首仪仗
        this.xunShou = xunShou; // 旬首
        this.xunShouYiZhang = xunShouYiZhang; // 旬首仪仗

    }

    /**
     * 计算旬空
     */
    private void xunKong() {

        // 1、设置旬空
        EightChar ec = getLunar().getEightChar();
        this.xunKong = Arrays.asList(ec.getYearXunKong(), ec.getMonthXunKong(), ec.getDayXunKong(), ec.getTimeXunKong());

    }

    /**
     * 计算值符和值使
     */
    private void fuShi() {

        // 1、根据旬首和六甲隐位获取旬首落宫
        for (int i = 0; i < getDiLiuJiaYinWei().size(); i++) {
            if (getXunShou().equals(getDiLiuJiaYinWei().get(i))) {
                this.xunShouGong = i + 1; // 旬首落宫（即：值符和值符落宫）
                this.oldZhiFuGong = i + 1; // 值符旋转前落宫
                this.oldZhiShiGong = i + 1; // 值使旋转前落宫
                break;
            }
        }

        // 2、根据旬首落宫获取[值符]和[值使]
        // 2.1、设置值符
        this.zhiFu = FeiShiJiaQiMenMap.JIU_XING_INITIAL[getXunShouGong() - 1];
        // 2.2、设置值使
        if (FeiShiJiaQiMenConstant.TIAN_QIN.equals(FeiShiJiaQiMenMap.JIU_XING_INITIAL[getXunShouGong() - 1]) || getXunShouGong() == 5) {
            String zhiShi = zhiShi(); // 计算并返回值使（天禽星为值符时：一律用[死门]为值使）
//            String zhiShi = zhiShi2(getYinYangDun()); // 计算并返回值使（天禽星为值符时：根据阴阳遁判断值使）
//            String zhiShi = zhiShi3(getJieQi()); // 计算并返回值使（天禽星为值符时：根据节气判断值使）
            this.zhiShi = zhiShi;
        } else {
            this.zhiShi = FeiShiJiaQiMenMap.JIU_MEN_INITIAL[getXunShouGong() - 1];
        }

    }

    /**
     * 计算六甲旬空、落宫、标识
     */
    private void liuJiaXunKong() {

        // 1、设置六甲旬空
        this.liuJiaXunKong = FeiShiJiaQiMenMap.LIU_JIA_XUN_KONG.get(getXunShou());

        // 2、设置六甲旬空落宫
        this.liuJiaXunKongGong = FeiShiJiaQiMenMap.LIU_JIA_XUN_KONG_GONG.get(getLiuJiaXunKong());

        // 3、设置六甲旬空落宫标识
        List<String> list = CommonUtil.addListEmpty(9);
        for (int i = 0; i < getLiuJiaXunKongGong().size(); i++) {
            list.set(getLiuJiaXunKongGong().get(i) - 1, FeiShiJiaQiMenConstant.KONG); // ○
        }
        this.liuJiaXunKongGongMark = list;

    }

    /**
     * 计算驿马、落宫、标识
     */
    private void yiMa() {

        String hourZhi = getHourZhi(); // 时支

        // 1、设置驿马
        this.yiMa = FeiShiJiaQiMenMap.YI_MA.get(hourZhi);

        // 2、设置驿马落宫
        this.yiMaGong = FeiShiJiaQiMenMap.YI_MA_GONG.get(getYiMa());

        // 3、设置驿马落宫标识
        List<String> list = CommonUtil.addListEmpty(9);
        list.set(getYiMaGong() - 1, FeiShiJiaQiMenConstant.MA); // 马
        this.yiMaGongMark = list;

    }

    /**
     * 计算地盘
     */
    private void diPan() {

        List<String> qiYi = getDiSanQiLiuYi(); // 三奇六仪
        List<String> liuJia = getDiLiuJiaYinWei(); // 六甲隐位

        // 合并（三奇六仪+六甲隐位）
        List<String> diPanPron = new ArrayList<>();
        for (int i = 0; i < qiYi.size(); i++) {
            for (int j = 0; j < liuJia.size(); j++) {
                if ("".equals(liuJia.get(j))) {
                    diPanPron.add(j, qiYi.get(i));
                } else {
                    diPanPron.add(j, qiYi.get(i) + "(" + liuJia.get(j) + ")");
                }
                i++;
            }
        }

        this.diPan = getDiSanQiLiuYi(); // 不附带六甲隐位（即：三奇六仪）
        this.diPanPron = diPanPron; // 附带六甲隐位（即：三奇六仪+六甲隐位）

    }

    /**
     * 计算天盘
     *
     * @param setting 设置
     */
    private void tianPan(FeiShiJiaQiMenSetting setting) {

        // 1、若时干为甲，则使用旬首仪仗进行判断
        String hourGan = getHourGan(); // 时干
        if (FeiShiJiaQiMenConstant.JIA_GAN.equals(hourGan)) {
            hourGan = getXunShouYiZhang();
        }

        // 2、计算时干落宫
        List<String> diSanQiLiuYi = getDiSanQiLiuYi(); // 地盘中的三奇六仪（1~9宫）
        for (int i = 0; i < diSanQiLiuYi.size(); i++) {
            if (hourGan.equals(diSanQiLiuYi.get(i))) {
                // 2.1、设置值符旋转后落入的宫位
                this.newZhiFuGong = i + 1;
                break;
            }
        }

        // 3、计算九星飞落的宫位（1~9宫）
        Map<Integer, List<String>> jiuXingFeiGong;
        if (setting.getTianPanFeiGong() == FeiShiJiaQiMenEnum.YIN_NI_FEI_YANG_SHUN_FEI.getMark()) {
            // 3.1、判断阴阳遁
            if (FeiShiJiaQiMenConstant.YANG_DUN.equals(getYinYangDun())) {
                // 3.2.1、阳遁顺飞九宫
                jiuXingFeiGong = FeiShiJiaQiMenMap.JIU_XING_SHUN_FEI; // 九星位置（顺飞九宫）
            } else {
                // 3.2.2、阴遁逆飞九宫
                jiuXingFeiGong = FeiShiJiaQiMenMap.JIU_XING_NI_FEI; // 九星位置（逆飞九宫）
            }
        } else {
            // 3.2、阴遁和阳遁一律顺飞九宫
            jiuXingFeiGong = FeiShiJiaQiMenMap.JIU_XING_SHUN_FEI; // 九星位置（顺飞九宫）
        }
        A:
        for (int i = 0; i < jiuXingFeiGong.size(); i++) {
            List<String> jiuXing = jiuXingFeiGong.get(i);
            for (int j = 0; j < jiuXing.size(); j++) {
                if (jiuXing.get(getNewZhiFuGong() - 1).equals(getZhiFu())) {
                    this.tianPan = jiuXingFeiGong.get(i);
                    break A;
                }
            }
        }

        // 4、计算原宫九星所携带的三奇六仪（1~9宫）
        Map<String, Integer> jiuXingInitial = FeiShiJiaQiMenMap.JIU_XING_INITIAL2; // 九星原始宫位（1~9宫）
        List<String> tianPanQiYi = new ArrayList<>(); // 存放原宫九星所携带的三奇六仪（1~9宫）
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < getDiSanQiLiuYi().size(); j++) {
                int index = jiuXingInitial.get(getTianPan().get(i)) - 1; // 九星原始宫位
                tianPanQiYi.add(i, getDiSanQiLiuYi().get(index)); // 九星原始宫位所携带的三奇六仪
                i++;
            }
        }

        // 5、设置天盘
        this.tianPanQiYi = tianPanQiYi;

    }

    /**
     * 计算人盘
     *
     * @param setting 设置
     */
    private void renPan(FeiShiJiaQiMenSetting setting) {

        String hourZhi = getHourZhi(); // 时支
        String[] zhi = FeiShiJiaQiMenMap.DI_ZHI; // 地支
        String xunShouZhi = getXunShou().substring(1, 2); // 旬首中的地支

        // 1、获取旬首中的地支在第几号索引
        int xunShouZhiIndex = 0; // 记录旬首中的地支索引
        for (int i = 0; i < zhi.length; i++) {
            if (xunShouZhi.equals(zhi[i])) {
                xunShouZhiIndex = i;
                break;
            }
        }

        // 2、接着旬首中的地支索引值向后查找时支所在位置
        int hourZhiCount = 0; // 记录找到时支时所需要查找的次数
        for (int i = 0; i < zhi.length; i++) {
            if (xunShouZhiIndex == zhi.length) {
                // 2.1、若查找至最后一个元素时仍未找到地支，则重置旬首中的地支索引值
                xunShouZhiIndex = 0;
            } else if (!hourZhi.equals(zhi[xunShouZhiIndex])) {
                // 2.2、未找到元素，继续查找
                hourZhiCount++; // 查找次数+1
                xunShouZhiIndex++; // 旬首中的地支索引+1
            } else {
                // 2.3、已找到元素，停止查找
                break;
            }
        }

        // 3、若[旬首中的地支]和[时支]不相同，说明值使落宫已改变
        int xunShouGong = getXunShouGong(); // 旬首落宫（即：值符和值符落宫）
        if (!xunShouZhi.equals(hourZhi)) {
            // 3.1、计算值使旋转后的宫位
            if (FeiShiJiaQiMenConstant.YANG_DUN.equals(getYinYangDun())) {
                // 3.1.1、阳遁用[值使旋转前宫位+一共查找的次数]获取旋转后值使所落宫位
                for (int i = 0; i < hourZhiCount; i++) {
                    // 3.1.2、若值使旋转后的宫位大于等于9，则重新从第一宫开始判断
                    if (xunShouGong >= 9) {
                        xunShouGong = 1;
                    } else {
                        xunShouGong++;
                    }
                }
            } else {
                // 3.2、阴遁用[值使旋转前宫位+一共查找的次数]获取旋转后值使所落宫位
                for (int i = 0; i < hourZhiCount; i++) {
                    // 3.2.1、若值使旋转后的宫位小于等于0，则重新从第九宫开始判断
                    if (xunShouGong <= 1) {
                        xunShouGong = 9;
                    } else {
                        xunShouGong--;
                    }
                }
            }
        }

        // 4、设置[值使]旋转后宫位
        this.newZhiShiGong = xunShouGong;

        Map<Integer, List<String>> jiuMenFeiGong;

        // 5、转宫
        if (setting.getRenPanFeiZhuan() == FeiShiJiaQiMenEnum.ZHUAN_GONG.getMark()) {
            if (setting.getRenPanZhuanGong() == FeiShiJiaQiMenEnum.YIN_NI_FEI_YANG_SHUN_ZHUAN.getMark()) {
                // 5.1、判断阴阳遁
                if (FeiShiJiaQiMenConstant.YANG_DUN.equals(getYinYangDun())) {
                    // 5.1.1、阳遁顺转九宫
                    jiuMenFeiGong = FeiShiJiaQiMenMap.BA_MEN_SHUN_ZHUAN; // 八门位置（顺转九宫）
                } else {
                    // 5.1.2、阴遁逆转九宫
                    jiuMenFeiGong = FeiShiJiaQiMenMap.BA_MEN_NI_ZHUAN; // 八门位置（逆转九宫）
                }
            } else {
                // 5.2、阴遁和阳遁一律顺转九宫
                jiuMenFeiGong = FeiShiJiaQiMenMap.BA_MEN_SHUN_ZHUAN; // 八门位置（顺转九宫）
            }
        } else {
            // 5、飞宫
            if (setting.getRenPanFeiGong() == FeiShiJiaQiMenEnum.YIN_NI_FEI_YANG_SHUN_FEI.getMark()) {
                // 5.1、判断阴阳遁
                if (FeiShiJiaQiMenConstant.YANG_DUN.equals(getYinYangDun())) {
                    // 5.1.1、阳遁顺飞九宫
                    jiuMenFeiGong = FeiShiJiaQiMenMap.JIU_MEN_SHUN_FEI; // 九门位置（顺飞九宫）
                } else {
                    // 5.1.2、阴遁逆飞九宫
                    jiuMenFeiGong = FeiShiJiaQiMenMap.JIU_MEN_NI_FEI; // 九门位置（逆飞九宫）
                }
            } else {
                // 5.2、阴遁和阳遁一律顺飞九宫
                jiuMenFeiGong = FeiShiJiaQiMenMap.JIU_MEN_SHUN_FEI; // 九门位置（顺飞九宫）
            }
        }

        // 6、计算人盘
        List<String> list = new ArrayList<>();
        for (int i = 0; i < jiuMenFeiGong.size(); i++) {
            List<String> jiuMen = jiuMenFeiGong.get(i);
            for (int j = 0; j < jiuMen.size(); j++) {
                if (jiuMen.get(getNewZhiShiGong() - 1).equals(getZhiShi())) {
                    list = jiuMen;
                    break;
                }
            }
        }

        // 7、设置人盘
        this.renPan = list;

    }

    /**
     * 计算神盘
     *
     * @param setting 设置
     */
    private void shenPan(FeiShiJiaQiMenSetting setting) {

        Map<Integer, List<String>> jiuShenFeiGong;

        if (setting.getShenPanFeiGong() == FeiShiJiaQiMenEnum.YIN_YANG_DUN_SHUN_FEI.getMark()) {
            // 1、阴遁和阳遁一律顺飞九宫
            jiuShenFeiGong = FeiShiJiaQiMenMap.JIU_SHEN_SHUN_FEI; // 九神位置（顺飞九宫）
        } else {
            // 2、判断阴阳遁
            if (FeiShiJiaQiMenConstant.YANG_DUN.equals(getYinYangDun())) {
                // 2.1、阳遁顺飞九宫
                jiuShenFeiGong = FeiShiJiaQiMenMap.JIU_SHEN_SHUN_FEI; // 九神位置（顺飞九宫）
            } else {
                // 2.2、阴遁逆飞九宫
                jiuShenFeiGong = FeiShiJiaQiMenMap.JIU_SHEN_NI_FEI; // 九神位置（逆飞九宫）
            }
        }

        // 3、设置神盘
        this.shenPan = jiuShenFeiGong.get(getNewZhiFuGong() - 1);

    }

    /**
     * 计算天乙、地乙、太乙
     */
    private void tianYiDiYiTaiYi() {

        /*
               天乙：值符飞落宫位的原宫星
               地乙：值使飞落宫位的原宫门
               太乙/元一：值使门
         */

        this.tianYi = FeiShiJiaQiMenMap.JIU_XING_INITIAL[getNewZhiFuGong() - 1]; // 天乙
        this.diYi = FeiShiJiaQiMenMap.JIU_MEN_INITIAL[getNewZhiShiGong() - 1]; // 地乙
        this.taiYi = getZhiShi(); // 太乙

    }

    /**
     * 计算六仪击刑
     */
    private void liuYiJiXing() {

        /*
            1、甲子戊：'戊'落震三宫，子卯相刑。
            2、甲戌己：'己'落坤二宫，戌未相刑。
            3、甲申庚：'庚'落艮八宫，申寅相刑。
            4、甲午辛：'辛'落离九宫，午午自刑。
            5、甲辰壬：'壬'落巽四宫，辰辰自刑。
            6、甲寅癸：'癸'落巽四宫，寅巳相刑。
        */

        List<String> list = new ArrayList<>(); // 保存六仪击刑
        List<String> tianPanQiYi = getTianPanQiYi(); // 天盘飞盘后九星所携带的三奇六仪（1~9宫）

        // 1.1、判断震三宫的天盘天干是否为'戊'
        if (FeiShiJiaQiMenConstant.WU_GAN.equals(tianPanQiYi.get(2))) {
            list.add(FeiShiJiaQiMenConstant.ZI_MAO_XING); // 子卯相刑(戊落震三宫)
        }
        // 1.2、判断坤二宫的天盘天干是否为'己'
        if (FeiShiJiaQiMenConstant.JI_GAN.equals(tianPanQiYi.get(1))) {
            list.add(FeiShiJiaQiMenConstant.XU_WEI_XING); // 戌未相刑(己落坤二宫)
        }
        // 1.3、判断艮八宫的天盘天干是否为'庚'
        if (FeiShiJiaQiMenConstant.GENG_GAN.equals(tianPanQiYi.get(7))) {
            list.add(FeiShiJiaQiMenConstant.SHEN_YIN_XING); // 申寅相刑(庚落艮八宫)
        }
        // 1.4、判断离九宫的天盘天干是否为'辛'
        if (FeiShiJiaQiMenConstant.XIN_GAN.equals(tianPanQiYi.get(8))) {
            list.add(FeiShiJiaQiMenConstant.WU_WU_XING); // 午午自刑(辛落离九宫)
        }
        // 1.5、判断巽四宫的天盘天干是否为'壬'
        if (FeiShiJiaQiMenConstant.REN_GAN.equals(tianPanQiYi.get(3))) {
            list.add(FeiShiJiaQiMenConstant.CHEN_CHEN_XING); // 辰辰自刑(壬落巽四宫)
        }
        // 1.6、判断巽四宫的天盘天干是否为'癸'
        if (FeiShiJiaQiMenConstant.GUI_GAN.equals(tianPanQiYi.get(3))) {
            list.add(FeiShiJiaQiMenConstant.YIN_SI_XING); // 寅巳相刑(癸落巽四宫)
        }

        this.liuYiJiXing = list;

    }

    /**
     * 计算奇仪入墓
     */
    private void qiYiRuMu() {

        /*
            1、'乙'落坤二宫、乾六宫。
            2、'丙'落乾六宫。
            3、'丁'落艮八宫。
            4、'戊'落乾六宫。
            5、'己'落艮八宫。
            6、'庚'落艮八宫。
            7、'辛'落巽四宫。
            8、'壬'落巽四宫。
            9、'癸'落坤二宫。
        */

        List<String> list = new ArrayList<>(); // 保存三奇六仪入墓
        List<String> tianPanQiYi = getTianPanQiYi(); // 天盘飞盘后九星所携带的三奇六仪（1~9宫）

        // 2.1、判断坤二宫的天盘天干是否为'乙'
        if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi.get(1))) {
            list.add(FeiShiJiaQiMenConstant.YI_ER_MU); // 乙入墓(坤二宫)
        }
        // 2.2、判断坤二宫的天盘天干是否为'癸'
        if (FeiShiJiaQiMenConstant.GUI_GAN.equals(tianPanQiYi.get(1))) {
            list.add(FeiShiJiaQiMenConstant.GUI_ER_MU); // 癸入墓(坤二宫)
        }
        // 2.3、判断乾六宫的天盘天干是否为'乙'
        if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi.get(5))) {
            list.add(FeiShiJiaQiMenConstant.YI_LIU_MU); // 乙入墓(乾六宫)
        }
        // 2.4、判断乾六宫的天盘天干是否为'丙'
        if (FeiShiJiaQiMenConstant.BING_GAN.equals(tianPanQiYi.get(5))) {
            list.add(FeiShiJiaQiMenConstant.BING_LIU_MU); // 丙入墓(乾六宫)
        }
        // 2.5、判断乾六宫的天盘天干是否为'戊'
        if (FeiShiJiaQiMenConstant.WU_GAN.equals(tianPanQiYi.get(5))) {
            list.add(FeiShiJiaQiMenConstant.WU_LIU_MU); // 戊入墓(乾六宫)
        }
        // 2.6、判断艮八宫的天盘天干是否为'丁'
        if (FeiShiJiaQiMenConstant.DING_GAN.equals(tianPanQiYi.get(7))) {
            list.add(FeiShiJiaQiMenConstant.DING_BA_MU); // 丁入墓(艮八宫)
        }
        // 2.7、判断艮八宫的天盘天干是否为'庚'
        if (FeiShiJiaQiMenConstant.GENG_GAN.equals(tianPanQiYi.get(7))) {
            list.add(FeiShiJiaQiMenConstant.GENG_BA_MU); // 庚入墓(艮八宫)
        }
        // 2.8、判断艮八宫的天盘天干是否为'己'
        if (FeiShiJiaQiMenConstant.JI_GAN.equals(tianPanQiYi.get(7))) {
            list.add(FeiShiJiaQiMenConstant.JI_BA_MU); // 己入墓(艮八宫)
        }
        // 2.9、判断巽四宫的天盘天干是否为'辛'
        if (FeiShiJiaQiMenConstant.XIN_GAN.equals(tianPanQiYi.get(3))) {
            list.add(FeiShiJiaQiMenConstant.XIN_SI_MU); // 辛入墓(巽四宫)
        }
        // 2.10、判断巽四宫的天盘天干是否为'壬'
        if (FeiShiJiaQiMenConstant.REN_GAN.equals(tianPanQiYi.get(3))) {
            list.add(FeiShiJiaQiMenConstant.REN_SI_MU); // 壬入墓(巽四宫)
        }

        this.qiYiRuMu = list;

    }

    /**
     * 计算十干克应
     */
    private void shiGanKeYing() {

        List<String> diPan = getDiPan(); // 地盘（1~9宫）
        Map<List<String>, List<String>> shiGanKeYing = FeiShiJiaQiMenMap.SHI_GAN_KE_YING; // 十干克应
        List<String> list = new ArrayList<>(); // 保存十干克应关系

        // 1、计算九宫中的[天盘天干+地盘天干]对应的十干克应关系
        for (int i = 0; i < 9; i++) {
            List<String> keYing = CommonUtil.addList(getTianPanQiYi().get(i), diPan.get(i)); // 天盘天干+地盘天干
            List<String> keYingListTo = shiGanKeYing.get(keYing); // 天盘天干+地盘天干的十干克应关系
            String keYingTo = keYing.get(0) + "+" + keYing.get(1) + "(" + keYingListTo.get(0) + ")：" + keYingListTo.get(1);
            list.add(i, keYingTo);
        }
        this.shiGanKeYing = list;

    }

    /**
     * 计算九遁
     */
    private void jiuDun() {

        List<String> list = new ArrayList<>(); //  保存单宫九遁
        Map<Integer, List<String>> map = new HashMap<>(); // 保存九宫九遁

        // 1、计算九遁
        List<String> tianDun = tianDun(); // 天遁
        List<String> diDun = diDun(); // 地遁
        List<String> renDun = renDun(); // 人遁
        List<String> shenDun = shenDun(); // 神遁
        List<String> guiDun = guiDun(); // 鬼遁
        List<String> fengDun = fengDun(); // 风遁
        List<String> yunDun = yunDun(); // 云遁
        List<String> longDun = longDun(); // 龙遁
        List<String> huDun = huDun(); // 虎遁

        // 2、整合九遁
        for (int i = 0; i < 9; i++) {
            if (!"".equals(tianDun.get(i))) list.add(tianDun.get(i));
            if (!"".equals(diDun.get(i))) list.add(diDun.get(i));
            if (!"".equals(renDun.get(i))) list.add(renDun.get(i));
            if (!"".equals(shenDun.get(i))) list.add(shenDun.get(i));
            if (!"".equals(guiDun.get(i))) list.add(guiDun.get(i));
            if (!"".equals(fengDun.get(i))) list.add(fengDun.get(i));
            if (!"".equals(yunDun.get(i))) list.add(yunDun.get(i));
            if (!"".equals(longDun.get(i))) list.add(longDun.get(i));
            if (!"".equals(huDun.get(i))) list.add(huDun.get(i));
            map.put(i, list);
            list = new ArrayList<>();
        }

        this.jiuDun = map;

    }

    /**
     * 计算月将、月将神
     */
    private void yueJiang() {

        String monthZhi = getMonthZhi(); // 月支
        this.yueJiang = FeiShiJiaQiMenMap.YUE_JIANG.get(monthZhi).get(0); // 月将
        this.yueJiangShen = FeiShiJiaQiMenMap.YUE_JIANG.get(monthZhi).get(1); // 月将神

    }

//------------------------------------------------------------------------------------------------------------------------------------

    /**
     * 计算并返回值使
     * <p>
     * <p> 天禽星为值符时：一律用[死门]为值使</p>
     *
     * @return 值使
     */
    private static String zhiShi() {

        return FeiShiJiaQiMenConstant.SI_MEN; // 死门

    }

    /**
     * 计算并返回值使
     * <hr/>
     * <p> 天禽星为值符时：阳遁用[生门]为值使</p>
     * <p> 天禽星为值符时：阴遁用[死门]为值使</p>
     *
     * @param yinYangDun 阴阳遁
     * @return 值使
     * @deprecated 使用zhiShi()
     */
    @Deprecated
    private static String zhiShi2(String yinYangDun) {

        // 阳遁用生门，阴遁用死门
        if (FeiShiJiaQiMenConstant.YANG_DUN.equals(yinYangDun)) {
            return FeiShiJiaQiMenConstant.SHENG_MEN; // 生门
        } else {
            return FeiShiJiaQiMenConstant.SI_MEN; // 死门
        }

    }

    /**
     * 计算并返回值使
     * <hr/>
     * <p>天禽星为值符时：（冬至、小寒、大寒）三个节气，用[休门]为值使</p>
     * <p>天禽星为值符时：（立春，雨水，惊蛰）三个节气，用[生门]为值使</p>
     * <p>天禽星为值符时：（春分、清明、谷雨）三个节气，用[伤门]为值使</p>
     * <p>天禽星为值符时：（立夏、小满、芒种）三个节气，用[杜门]为值使</p>
     * <p>天禽星为值符时：（夏至、小暑、大暑）三个节气，用[景门]为值使</p>
     * <p>天禽星为值符时：（立秋、处暑、白露）三个节气，用[死门]为值使</p>
     * <p>天禽星为值符时：（秋分、寒露、霜降）三个节气，用[惊门]为值使</p>
     * <p>天禽星为值符时：（立冬、小雪、大雪）三个节气，用[开门]为值使</p>
     *
     * @param jieQi 节气
     * @return 值使
     * @deprecated 使用zhiShi()
     */
    @Deprecated
    private static String zhiShi3(String jieQi) {

        Map<Integer, List<String>> isBaMen = FeiShiJiaQiMenMap.IS_BA_MEN; // 根据二十四节气获取八门

        // 根据二十四节气判断八门
        for (int i = 0; i < isBaMen.size(); i++) {
            for (int j = 0; j < isBaMen.get(i).size(); j++) {
                String s = isBaMen.get(i).get(j);
                if (s.equals(jieQi)) {
                    switch (i) {
                        case 0:
                            return FeiShiJiaQiMenConstant.XIU_MEN; // 休门
                        case 1:
                            return FeiShiJiaQiMenConstant.SHENG_MEN; // 生门
                        case 2:
                            return FeiShiJiaQiMenConstant.SHANG_MEN; // 伤门
                        case 3:
                            return FeiShiJiaQiMenConstant.DU_MEN; // 杜门
                        case 4:
                            return FeiShiJiaQiMenConstant.JING_MEN_1; // 景门
                        case 5:
                            return FeiShiJiaQiMenConstant.SI_MEN; // 死门
                        case 6:
                            return FeiShiJiaQiMenConstant.JING_MEN_2; // 惊门
                        case 7:
                            return FeiShiJiaQiMenConstant.KAI_MEN; // 开门
                    }
                }
            }
        }

        return "";

    }

    /**
     * 计算并返回天遁
     */
    private List<String> tianDun() {

        /*
            天盘[丙奇(月奇)]加地盘[六丁]合人盘[开门、休门、生门]。即【丙+丁+开门、休门、生门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        for (int i = 0; i < 9; i++) {
            String tianPanQiYi = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
            String diPan = getDiPan().get(i); // 每一宫位中的奇仪
            String renPan = getRenPan().get(i); // 每一宫位中的门
            // 判断宫位信息是否符合→ 天盘[丙奇(月奇)]加地盘[六丁]合人盘[开门、休门、生门]。
            if (FeiShiJiaQiMenConstant.BING_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.DING_GAN.equals(diPan) &&
                    (FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan) || FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan))) {
                list.set(i, FeiShiJiaQiMenConstant.TIAN_DUN);
            }
        }

        return list;

    }

    /**
     * 计算并返回地遁
     */
    private List<String> diDun() {

        /*
            天盘[乙奇(日奇)]加地盘[六己]合人盘[开门、休门、生门]。即【乙+己+开门、休门、生门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        for (int i = 0; i < 9; i++) {
            String tianPanQiYi = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
            String diPan = getDiPan().get(i); // 每一宫位中的奇仪
            String renPan = getRenPan().get(i); // 每一宫位中的门
            // 判断宫位信息是否符合→ 天盘[乙奇(日奇)]加地盘[六己]合人盘[开门、休门、生门]。
            if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.JI_GAN.equals(diPan) &&
                    (FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan) || FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan))) {
                list.set(i, FeiShiJiaQiMenConstant.DI_DUN);
            }
        }

        return list;

    }

    /**
     * 计算并返回人遁
     */
    private List<String> renDun() {

        /*
            天盘[丁奇(星奇)]加神盘[太阴]合人盘[休门]。即【丁+太阴+休门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        for (int i = 0; i < 9; i++) {
            String tianPanQiYi = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
            String shenPan = getShenPan().get(i); // 每一宫位中的神
            String renPan = getRenPan().get(i); // 每一宫位中的门
            // 判断宫位信息是否符合→ 天盘[丁奇(星奇)]加神盘[太阴]合人盘[休门]。
            if (FeiShiJiaQiMenConstant.DING_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.TAI_YIN.equals(shenPan) && FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan)) {
                list.set(i, FeiShiJiaQiMenConstant.REN_DUN);
            }
        }

        return list;

    }

    /**
     * 计算并返回神遁
     */
    private List<String> shenDun() {

        /*
            天盘[丙奇(月奇)]加神盘[九天]合人盘[生门]。即【丙+九天+生门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        for (int i = 0; i < 9; i++) {
            String tianPanQiYi = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
            String shenPan = getShenPan().get(i); // 每一宫位中的神
            String renPan = getRenPan().get(i); // 每一宫位中的门
            // 判断宫位信息是否符合→ 天盘[丙奇(月奇)]加神盘[九天]合人盘[生门]。
            if (FeiShiJiaQiMenConstant.BING_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.JIU_TIAN.equals(shenPan) && FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan)) {
                list.set(i, FeiShiJiaQiMenConstant.SHEN_DUN);
            }
        }

        return list;

    }

    /**
     * 计算并返回鬼遁
     */
    private List<String> guiDun() {

        /*
            天盘[丁奇(星奇)]加神盘[九地]合人盘[杜门、开门]。即【丙+九天+生门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        for (int i = 0; i < 9; i++) {
            String tianPanQiYi = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
            String shenPan = getShenPan().get(i); // 每一宫位中的神
            String renPan = getRenPan().get(i); // 每一宫位中的门
            // 判断宫位信息是否符合→ 天盘[丁奇(星奇)]加神盘[九地]合人盘[杜门、开门]。
            if (FeiShiJiaQiMenConstant.DING_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.JIU_DI.equals(shenPan) &&
                    (FeiShiJiaQiMenConstant.DU_MEN.equals(renPan) || FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan))) {
                list.set(i, FeiShiJiaQiMenConstant.GUI_DUN);
            }
        }

        return list;

    }

    /**
     * 计算并返回风遁
     */
    private List<String> fengDun() {

        /*
            天盘[乙奇(日奇)]加人盘[开门、休门、生门]临[巽四宫]。即【乙+巽四宫+开门、休门、生门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        // 1、获取巽四宫信息
        int gongWei = 3; // 巽四宫对应索引值为3
        String tianPanQiYi = getTianPanQiYi().get(gongWei); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
        String renPan = getRenPan().get(gongWei); // 巽四宫中的门

        // 2、判断巽四宫信息是否符合→ 天盘[乙奇(日奇)]加人盘[开门、休门、生门]临[巽四宫]。
        if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi) &&
                (FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan) || FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan))) {
            list.set(gongWei, FeiShiJiaQiMenConstant.FENG_DUN);
        }

        return list;

    }

    /**
     * 计算并返回云遁
     */
    private List<String> yunDun() {

        /*
            天盘[乙奇(日奇)]加地盘[六辛]合人盘[开门、休门、生门]。即【乙+辛+开门、休门、生门】。
         */

        List<String> list = CommonUtil.addListEmpty(9);

        for (int i = 0; i < 9; i++) {
            String tianPanQiYi = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
            String diPan = getDiPan().get(i); // 每一宫位中的奇仪
            String renPan = getRenPan().get(i); // 每一宫位中的门
            // 宫位信息是否符合→ 天盘[乙奇(日奇)]加地盘[六辛]合人盘[开门、休门、生门]。
            if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.XIN_GAN.equals(diPan) &&
                    (FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan) || FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan))) {
                list.set(i, FeiShiJiaQiMenConstant.YUN_DUN);
            }
        }

        return list;

    }

    /**
     * 计算并返回龙遁
     */
    private List<String> longDun() {

        /*
            1、天盘[乙奇(日奇)]加人盘[开门、休门、生门]临[坎一宫]。即【乙+坎一宫+开门、休门、生门】
            2、天盘[乙奇(日奇)]加地盘[六癸]合人盘[开门、休门、生门]。即【乙+癸+开门、休门、生门】
         */

        List<String> list = CommonUtil.addListEmpty(9);

        // 1、获取坎一宫信息
        int gongWei = 0; // 坎一宫对应索引值为0
        String tianPanQiYi = getTianPanQiYi().get(gongWei); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
        String renPan = getRenPan().get(gongWei); // 坎一宫门

        // 2、判断坎一宫信息是否符合→ 天盘[乙奇(日奇)]加人盘[开门、休门、生门]临[坎一宫]。
        if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi) &&
                (FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan) || FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan))) {
            list.set(gongWei, FeiShiJiaQiMenConstant.LONG_DUN);
        } else {
            // 2.1、判断1~9宫信息
            for (int i = 0; i < 9; i++) {
                String tianPanQiYi2 = getTianPanQiYi().get(i); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
                String diPan2 = getDiPan().get(i); // 每一宫位中的奇仪
                String renPan2 = getRenPan().get(i); // 每一宫位中的八门
                // 2.2、判断宫位信息是否符合→ 天盘[乙奇(日奇)]加地盘[六癸]合人盘[开门、休门、生门]。
                if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi2) && FeiShiJiaQiMenConstant.GUI_GAN.equals(diPan2) &&
                        (FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan2) || FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan2) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan2))) {
                    list.set(i, FeiShiJiaQiMenConstant.LONG_DUN);
                }
            }
        }

        return list;

    }

    /**
     * 计算并返回虎遁
     */
    private List<String> huDun() {

        /*
            1、天盘[六庚]加人盘[开门]临[兑七宫]。即【庚+兑七宫+开门】
            2、天盘[乙奇(日奇)]加地盘[六辛]合人盘[休门、生门]临[艮八宫]。即【乙+辛+艮八宫+休门、生门】
         */

        List<String> list = CommonUtil.addListEmpty(9);

        // 1、获取兑七宫信息
        int gongWei = 6; // 兑七宫对应索引值为6
        String tianPanQiYi = getTianPanQiYi().get(gongWei); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
        String renPan = getRenPan().get(gongWei); // 兑七宫门

        // 2、获取艮八宫信息
        int gongWei2 = 7; // 艮八宫对应索引值为7
        String tianPanQiYi2 = getTianPanQiYi().get(gongWei); // 每一宫位中的天盘飞盘后九星所携带的三奇六仪（1~9宫）
        String diPan2 = getDiPan().get(gongWei2); // 艮八宫奇仪
        String renPan2 = getRenPan().get(gongWei2); // 艮八宫门

        // 3、判断兑七宫信息是否符合→ 天盘[六庚]加人盘[开门]临[兑七宫]。
        if (FeiShiJiaQiMenConstant.GENG_GAN.equals(tianPanQiYi) && FeiShiJiaQiMenConstant.KAI_MEN.equals(renPan)) {
            list.set(gongWei, FeiShiJiaQiMenConstant.HU_DUN);
        } else {
            // 3.1、判断艮八宫信息是否符合→ 天盘[乙奇(日奇)]加地盘[六辛]合人盘[休门、生门]临[艮八宫]
            if (FeiShiJiaQiMenConstant.YI_GAN.equals(tianPanQiYi2) && FeiShiJiaQiMenConstant.XIN_GAN.equals(diPan2) &&
                    (FeiShiJiaQiMenConstant.XIU_MEN.equals(renPan2) || FeiShiJiaQiMenConstant.SHENG_MEN.equals(renPan2))) {
                list.set(gongWei, FeiShiJiaQiMenConstant.HU_DUN);
            }
        }

        return list;

    }

    /**
     * 获取公历日期
     *
     * @return 公历日期（如：2023年6月15日12时）
     */
    public String getSolarStr() {

        return FeiShiJiaQiMenUtil.getSolarStr(getSolar());

    }

    /**
     * 获取农历日期
     *
     * @return 农历日期（如：二〇二三年四月廿八午时）
     */
    public String getLunarStr() {

        return FeiShiJiaQiMenUtil.getLunarStr(getLunar());

    }

    @Override
    public String toString() {

        StringBuilder s = new StringBuilder();

        s.append("公历").append(getSolarStr());
        s.append("   ");
        s.append("农历").append(getLunarStr());
        s.append("   ");
        s.append("星期:").append(getWeek());
        s.append("   ");
        s.append("八字:").append(getBaZi());
        s.append("   ");
        s.append("八字五行:").append(getBaZiWuXing());
        s.append("   ");
        s.append("八字纳音:").append(getBaZiNaYin());
        s.append("   ");
        s.append("八字旬空:").append(getBaZiXunKong());
        s.append("   ");
        s.append("符头:").append(getFuTou());
        s.append("   ");
        s.append("节气:").append(getJieQi()).append(getSanYuan());
        s.append("   ");
        s.append("局数:").append(getYinYangDun()).append(getJuShu()).append("局");
        s.append("   ");
        s.append("旬首:").append(getXunShou());
        s.append("   ");
        s.append("值符:").append(getZhiFu());
        s.append("   ");
        s.append("值使:").append(getZhiShi());
        s.append("   ");
        s.append("天乙:").append(getTianYi());
        s.append("   ");
        s.append("地乙:").append(getDiYi());
        s.append("   ");
        s.append("太乙:").append(getZhiShi());
        s.append("   ");
        s.append("地盘:").append(getDiPan());
        s.append("   ");
        s.append("天盘:").append(getTianPan());
        s.append("   ");
        s.append("人盘:").append(getRenPan());
        s.append("   ");
        s.append("神盘:").append(getShenPan());
        s.append("   ");
        s.append("六仪击刑:").append(getLiuYiJiXing());
        s.append("   ");
        s.append("奇仪入墓:").append(getQiYiRuMu());
        s.append("   ");
        s.append("月将:").append(getYueJiang());
        s.append("   ");
        s.append("月将神:").append(getYueJiangShen());

        return s.toString();

    }


}
